package cn.saltice.idempotence.idem.distributed;

import cn.saltice.idempotence.idem.warpper.IdempotentRunnable;
import cn.saltice.idempotence.idem.warpper.IdempotentSupplier;

import java.util.concurrent.TimeUnit;

/**
 * @program: idempotence
 * @description: 分布式锁接口，锁的释放时间一定要考虑好，不然业务处理时间太长了，导致锁被释放了，然后又调用了unLock()方法，就会出现错误
 * @author: Mr.Liu
 * @create: 2020-10-04 19:42
 **/
public interface DistributedLock {
    /**
     * 加锁
     * @param key 锁key
     * @param waitTime 尝试加锁，等待时间（ms）
     * @param leaseTime 上锁后的失效时间（ms）
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     * @param <T>
     * @return
     */
    <T> T lock(String key, int waitTime, int leaseTime, IdempotentSupplier<T> success, IdempotentSupplier<T> fail);

    /**
     * 加锁，加锁失败立即返回
     * @param key 锁key
     * @param leaseTime 上锁后的失效时间（ms）
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     * @param <T>
     * @return
     */
    <T> T lock(String key, int leaseTime, IdempotentSupplier<T> success, IdempotentSupplier<T> fail);

    /**
     * 加锁，加锁失败立即返回
     * @param key 锁key
     * @param leaseTime 上锁后的失效时间（ms）
     * @param timeUnit 时间单位
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     * @param <T>
     * @return
     */
    <T> T lock(String key, int leaseTime, TimeUnit timeUnit, IdempotentSupplier<T> success, IdempotentSupplier<T> fail);

    /**
     * 加锁
     * @param key 锁key
     * @param waitTime 尝试加锁，等待时间（ms）
     * @param leaseTime 上锁后的失效时间（ms）
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     */
    void lock(String key, int waitTime, int leaseTime, IdempotentRunnable success, IdempotentRunnable fail);

    /**
     * 加锁，加锁失败立即返回
     * @param key 锁key
     * @param leaseTime 上锁后的失效时间（ms）
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     */
    void lock(String key, int leaseTime, IdempotentRunnable success, IdempotentRunnable fail);

    /**
     * 加锁，加锁失败立即返回
     * @param key 锁key
     * @param leaseTime 上锁后的失效时间
     * @param timeUnit 时间单位
     * @param success 锁成功执行的逻辑
     * @param fail 锁失败执行的逻辑
     */
    void lock(String key, int leaseTime, TimeUnit timeUnit, IdempotentRunnable success, IdempotentRunnable fail);

}
